package org.firestorm.traficforecast.utils;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

public class ReadXML {
	private final String[] wayType = { "motorway", "trunk", "primary",
			"secondary", "tertiary", "unclassified", "residential", "service" };

	public static void main(String[] args) {
		ReadXML xml = new ReadXML();
		File fXmlFile = new File(
				"E:\\HOC TAP\\KI 20141\\Project\\TAI LIEU\\hbt.osm");
		DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
		DocumentBuilder dBuilder;
		try {
			dBuilder = dbFactory.newDocumentBuilder();
			Document doc = dBuilder.parse(fXmlFile);
			doc.getDocumentElement().normalize();

			NodeList ways = doc.getElementsByTagName("way");
			System.out.println(ways.getLength());
			int count = 0;
			int waysLen = ways.getLength();
			for (int i = 0; i < waysLen; i++) {
				if (xml.isRoad(ways.item(i))) {
					Element way = (Element) ways.item(i);
					String id = way.getAttribute("id");
					String name = xml.getName(ways.item(i));
					NodeList ndList = way.getElementsByTagName("nd");
					int ndListLen = ndList.getLength();
					ArrayList<String> indexs = new ArrayList<String>();
					Element firt = (Element) ndList.item(0);
					indexs.add(firt.getAttribute("ref"));
					
					ArrayList<String> nodeInRoad = new ArrayList<String>();
					String tmp = firt.getAttribute("ref");
					
					for (int k = 1; k < ndListLen; k++) {
						Element nd = (Element) ndList.item(k);
						String ref = nd.getAttribute("ref");
						tmp += "," + ref;
						
						for (int j = 0; j < i; j++) {
							if (xml.inRoad(nd, ways.item(j))) {
								if (indexs.indexOf(ref) < 0) {
									indexs.add(ref);
									nodeInRoad.add(tmp);
									tmp = ref;
								}
								break;
							}
						}
						for (int j = i + 1; j < waysLen; j++) {
							if (xml.inRoad(nd, ways.item(j))) {
								if (indexs.indexOf(ref) < 0) {
									indexs.add(ref);
									nodeInRoad.add(tmp);
									tmp = ref;
								}
								break;
							}
						}
					}

					// road here
					int a = 0;
					int b = 1;
					while (a < indexs.size() - 1) {
						while (b <= indexs.size() - 1) {
							if (xml.isOneway(ways.item(i))) {
								System.out.print(id + a + ". " + name + ":" + indexs.get(a) + "[[" + nodeInRoad.get(a) + "]]" + ", "
										+ indexs.get(b) + " -- ");
								a = b;
								b++;
								count += 1;
							} else {
								System.out.print(id + a + ". " + name + ":" + indexs.get(a) + "[[" + nodeInRoad.get(a) + "]]" + ", "
										+ indexs.get(b) + " -- "
										+ id + a + a +". " + name + ":" + indexs.get(b) + "[[" + nodeInRoad.get(a) + "]]" + ", " + indexs.get(a)
										+ " -- ");
								a = b;
								b++;
								count += 2;
							}
						}
					}
					System.out.println();
					System.out.println("Number of road: " + count);
				}
			}

		} catch (ParserConfigurationException e) {
			e.printStackTrace();
		} catch (SAXException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	private boolean isRoad(String type) {
		for (int i = 0; i < wayType.length; i++) {
			if (type.equals(wayType[i])) {
				return true;
			}
		}
		return false;
	}

	private boolean isRoad(Node way) {
		Element e = (Element) way;
		NodeList tagList = e.getElementsByTagName("tag");
		for (int i = 0; i < tagList.getLength(); i++) {
			Node tag = tagList.item(i);
			Element eTag = (Element) tag;
			if ("highway".equals(eTag.getAttribute("k"))) {
				if (isRoad(eTag.getAttribute("v"))) {
					return true;
				}
			}
		}
		return false;
	}

	private String getName(Node way){
		Element e = (Element) way;
		NodeList tagList = e.getElementsByTagName("tag");

		for (int i = 0; i < tagList.getLength(); i++) {
			Node tag = tagList.item(i);
			Element eTag = (Element) tag;
			if ("name".equals(eTag.getAttribute("k"))) {
				return eTag.getAttribute("v");
			}
		}
		return "unknow";
	}
	
	private boolean isOneway(Node way) {
		Element e = (Element) way;
		NodeList tagList = e.getElementsByTagName("tag");

		for (int i = 0; i < tagList.getLength(); i++) {
			Node tag = tagList.item(i);
			Element eTag = (Element) tag;
			if ("oneway".equals(eTag.getAttribute("k"))) {
				if ("yes".equals(eTag.getAttribute("v"))) {
					return true;
				}
			}
		}
		return false;
	}

	private boolean inRoad(Element ndTag, Node wayNode) {
		Element way = (Element) wayNode;
		NodeList ndList = way.getElementsByTagName("nd");
		int len = ndList.getLength();
		for (int i = 0; i < len; i++) {
			Element e = (Element) ndList.item(i);
			if (ndTag.getAttribute("ref").equals(e.getAttribute("ref"))) {
				return true;
			}
		}
		return false;
	}

}
